"""
定义一个用于创建对象的接口（工厂接口），让子类决定实例化哪一个产品类
"""
from abc import abstractmethod, ABCMeta


# 抽象产品角色（Product）
class Payment(metaclass=ABCMeta):
    @abstractmethod  # 抽象类，表示如果有子类继承这个父类，那么这个方法就必须要实现
    def pay(self, money):
        pass


# 具体产品角色（Concrete Product）
class Alipay(Payment):
    """支付宝支付"""

    def __init__(self, huabei=False):
        self.huabei = huabei  # huabei=True,表示使用花呗付款

    def pay(self, money):
        if self.huabei:
            print("花呗支付%d" % money)
        else:
            print("支付宝支付%d" % money)


# 具体产品角色（Concrete Product）
class WechatPay(Payment):
    """微信支付"""

    def pay(self, money):
        print("微信支付%d" % money)


# 抽象工厂角色（Creator）
class PaymentFactory(metaclass=ABCMeta):
    """创建工厂类，不暴露微信支付宝支付的方法，只用输入alipay，wechat,huabei，就可以调用相应的方法.这样外部就不知道我们内部是怎么样实现的"""

    @abstractmethod
    def create_payment(self):
        pass


# 具体工厂角色（Concrete Creator）
class AlipayFactory(PaymentFactory):

    def create_payment(self):
        return Alipay()


class WechatFactory(PaymentFactory):
    def create_payment(self):
        return WechatPay()


class HuabeiFactory(PaymentFactory):
    def create_payment(self):
        return Alipay(huabei=True)


# 把一个工厂类通过，抽象工厂的方式，拆分成多个具体的工厂类。（让用户调用的时候看不到我们处理代码的逻辑）
pf = HuabeiFactory()
# 外部调用只用知道alipay，wechat,huabei，不会知道我们内部是怎么样实现的
a = pf.create_payment()
a.pay(500)
